package top.jle.spring.basic.interceptor;

import cn.hutool.http.useragent.Browser;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import top.jle.spring.basic.annotation.InterfaceToken;
import top.jle.spring.basic.annotation.PassToken;
import top.jle.spring.basic.config.URLTrackingProperties;
import top.jle.spring.basic.config.WebProperties;
import top.jle.spring.basic.util.GlobalThreadLocalUtil;
import top.jle.spring.basic.util.IPUtil;
import top.jle.spring.basic.util.JWTHandler;

import java.lang.reflect.Method;
@Slf4j
public class GlobalInterceptor implements AsyncHandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalInterceptor.class);

    private final WebProperties.AuthConfig authConfig;
    @Resource
    private URLTrackingProperties trackingConfig;

    public GlobalInterceptor(WebProperties.AuthConfig authConfig) {
        this.authConfig = authConfig;
        log.info("GlobalInterceptor init");
        Browser.addCustomBrowser("Aweme","aweme",Browser.Other_Version);
    }

    @Autowired
    private JWTHandler jwtHandler;
    @Autowired(required = false)
    private RedissonClient redissonClient;
    @Override
    public boolean preHandle(HttpServletRequest request, @Nonnull HttpServletResponse response,@Nonnull Object handler) {


        String token = request.getHeader(authConfig.getTokenHeader());// 从 http 请求头中取出 token
        StringBuilder paramString = new StringBuilder();
        GlobalThreadLocalUtil.setIp(IPUtil.getClientIp(request));
        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod handlerMethod)){
            return true;
        }
        if(request.getRequestURI().contains("/error")){
            return true;
        }
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释，有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            return true;
        }
        if(method.isAnnotationPresent(InterfaceToken.class)){
            //接口Token校验
            interfaceTokenVerify(token);
            return true;
        }else{
            if(authConfig.isEnableSuperToken()&& authConfig.getSuperToken().equals(token)){
                return true;
            }
            //用户token校验
            jwtHandler.validateToken(token);
            handleTracking(request);
            return true;
        }
    }

    private void handleTracking(HttpServletRequest request){
        if (trackingConfig.isEnable() && redissonClient!=null) {

            JSONObject trackObj = GlobalThreadLocalUtil.getJwtBody();
            trackObj.fluentPut("ip", GlobalThreadLocalUtil.getIp())
                    .fluentPut("url",request.getRequestURI())
                    .fluentPut("fullUrl",request.getRequestURL())
                    .fluentPut("time",System.currentTimeMillis());
            //发布埋点事件
            redissonClient.getTopic(trackingConfig.getTrackChannel()).publish(trackObj);
        }
    }

    private void interfaceTokenVerify(String token){

        if(!authConfig.getInterfaceToken().equals(token)){
            jwtHandler.validateToken(token);
        }
    }

    @Override
    public void afterCompletion(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull Object handler, Exception ex) throws Exception {
        GlobalThreadLocalUtil.clearAll();
        AsyncHandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

}
